#ifndef RULES_C
#define RULES_C
#include "rules.h"
static unsigned char protocols[] = {PROT_ICMP,PROT_TCP,PROT_UDP,LAST_RULE_PROT};

static unsigned int fw_config = 0; // firewall config 

static rule_t* rulesPtr = NULL;    // Global variable for rules pointer

static void loadDefaultRules(void){
	rule_t defaultRules[NUM_OF_DEF_RULES] = {0};
	int i;	
	printk("\n local host = %u \n",LOCALHOST);
	// construct default rules
	for(i=0;i<NUM_OF_DEF_RULES;i++){
		defaultRules[i].protocol = protocols[i];
		defaultRules[i].src_ip = LOCALHOST;
		defaultRules[i].dst_ip = LOCALHOST;
		defaultRules[i].src_port = PORT_WILDCARD;
		defaultRules[i].dst_port = PORT_WILDCARD;
		defaultRules[i].src_mask = MAX_BITS_MASK;
		defaultRules[i].dst_mask = MAX_BITS_MASK;
		defaultRules[i].action = NF_ACCEPT;
	}	
	// copy rules 
	if(rulesPtr != NULL)
		memcpy(rulesPtr,defaultRules,sizeof(rule_t)*NUM_OF_DEF_RULES);		
	else
		printk("\n rulesPtr is NULL \n");
}

//All ips are in computer endian
static __u32 applyMaskToIP(__u32 ip, __u8 mask){
	printk("Apply Mask To IP\n");
	printk("IP = %u MASK = %u\n",ip,mask);
	return (ip  >> (MAX_BITS_MASK - mask)) << (MAX_BITS_MASK - mask);	
}


static char checkPermission(rawPacket_t* packet,int *matchedIndex){
	rule_t* nextRule = rulesPtr;
	int count = 0;
	int sPort = 0, dPort = 0; 
	
	while(nextRule->protocol != LAST_RULE_PROT && count < RULE_BASE_ENTRIES){				
		if(nextRule->protocol == packet->protocol){
			if(ntohl(nextRule->src_ip)  == applyMaskToIP(ntohl(packet->source_ip),nextRule->src_mask)  && 
			   ntohl(nextRule->dst_ip)  == applyMaskToIP(ntohl(packet->dest_ip),nextRule->dst_mask)){
				sPort = (nextRule->src_port == 0)?1:(nextRule->src_port == packet->source_port)?1:0;
				dPort = (nextRule->src_port == 0)?1:(nextRule->src_port == packet->dest_port)?1:0;
				if(sPort && dPort){								
					printk("\nRule Applied");
					*matchedIndex = count;
					return nextRule->action;	
				}else{
					printk("\nRule didnt apply");
				}
			}
		}		
		++nextRule;
		++count;
	}
	return UNMATCHED_PACKET;
}

	

#endif
